package org.truenewx.tnxjee.core.boot;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.truenewx.tnxjee.core.util.BeanUtil;
import org.truenewx.tnxjee.core.util.LogUtil;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ApplicationContextRunnerExecutor implements ApplicationRunner {

    @Autowired
    private ApplicationContext context;
    @Autowired
    private ScheduledExecutorService executor;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        Map<String, ApplicationContextRunner> beans = this.context.getBeansOfType(ApplicationContextRunner.class);
        List<ApplicationContextRunner> list = new ArrayList<>(beans.values());
        list.sort(Comparator.comparingInt(ApplicationContextRunner::getOrder));
        for (ApplicationContextRunner bean : list) {
            if (bean instanceof ApplicationContextDelayRunner) {
                ApplicationContextDelayRunner runner = (ApplicationContextDelayRunner) bean;
                this.executor.schedule(() -> {
                    try {
                        runner.run(this.context);
                    } catch (Exception e) {
                        LogUtil.error(BeanUtil.getUltimateClass(runner), e);
                    }
                }, runner.getDelayMillis(), TimeUnit.MILLISECONDS);
            } else {
                try {
                    bean.run(this.context);
                } catch (Exception e) {
                    LogUtil.error(getClass(), e);
                }
            }
        }
    }
}
